package com.example.demo3;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

/**
 * 案例三：jdk8新时间的应用(方法二)
 */
public class Test2 {
    // 定义首次休息日为2024年2月1日
    public static final LocalDate FIRST_REST_DAY = LocalDate.of(2024, 2, 1);

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入查询月份（格式：YYYY-MM）:");
        // 用户输入的日期
        String input = sc.nextLine();
        // 获取年份和月份
        int year = Integer.parseInt(input.substring(0, 4));
        int month = Integer.parseInt(input.substring(5, 7));

        // 1.计算该月最大天数
        LocalDate startDate = LocalDate.of(year, month, 1); // 设置起始日期为当月的第一天
        LocalDate endDate = startDate.with(TemporalAdjusters.lastDayOfMonth()); // 获取当月的最后一天
        int maxDay = endDate.getDayOfMonth(); // 获取当月的最大天数
        System.out.println("该月最后一天是：" + endDate);

        // 2.计算首次休息日到输入月份的间隔天数
        long intervalDays = ChronoUnit.DAYS.between(FIRST_REST_DAY, endDate); // 计算两个日期之间的天数差

        // 3.计算间隔天数中的所有休息日，并存入到集合中
        List<LocalDate> allRestDays = findRestDays(intervalDays);

        System.out.println("从" + FIRST_REST_DAY + "到" + endDate + "所有休息日如下：" + allRestDays);

        // 找出输入月份中下的休息日
        List<LocalDate> restDaysInMonth = findRestDaysInMonth(allRestDays, startDate, endDate);

        System.out.println("输入月份中休息日如下：" + restDaysInMonth);

        // 找出输入月份中周末的天数
        restDaysInMonth.stream().filter(d -> d.getDayOfWeek() == DayOfWeek.SATURDAY || d.getDayOfWeek() == DayOfWeek.SUNDAY)
                .forEach(d -> System.out.print(d + (d.getDayOfWeek() == DayOfWeek.SATURDAY ? "周六" : "周日")));
    }

    /**
     * 找出输入月份中的所有休息日
     *
     * @param allRestDays 所有休息日的集合
     * @param startDate   输入月份起始日期
     * @param endDate     输入月份结束时间
     * @return 输入月份中的所有休息日
     */
    private static List<LocalDate> findRestDaysInMonth(List<LocalDate> allRestDays, LocalDate startDate, LocalDate endDate) {
        return allRestDays.stream()
                // 过滤出在 startDate 和 endDate 之间的休息日(包括 startDate 和 endDate)
                .filter(restDay -> restDay.isAfter(startDate.minusDays(1)) && restDay.isBefore(endDate.plusDays(1)))
                .collect(Collectors.toList());
    }

    /**
     * 计算从首先休息日开始的所以休息日
     *
     * @param intervalDays 间隔天数
     * @return 所以休息日的日期集合
     */
    private static List<LocalDate> findRestDays(long intervalDays) {
        // 创建一个所有休息日的集合
        List<LocalDate> restDays = new ArrayList<>();
        LocalDate currentRestDay = FIRST_REST_DAY; // 从首次休息日开始
        for (int i = 0; i < intervalDays; i += 3) { // 每3天是一个循环 即上两天班休息一天
            restDays.add(currentRestDay);
            currentRestDay = currentRestDay.plusDays(3);
        }
        return restDays;
    }
}
